package com.corpgovernment.common.requestprocess;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import org.apache.commons.lang3.StringUtils;

import com.corpgovernment.common.common.CorpBusinessException;
import com.ctrip.corp.obt.generic.exception.ResponseStatus;

/**
 * 封装一些基本的校验，如字符串非空，对象非null
 * 
 * @author dlz
 * @since 2021/12/1
 */
public final class VerifyUtil {

    private VerifyUtil() {}

    /**
     * 验证value不为空字符串
     * 
     * @param value 待验证字符串
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyNotBlank(String value, ResponseStatus errorEnum) throws CorpBusinessException {
        if (StringUtils.isBlank(value)) {
            throw new CorpBusinessException(errorEnum);
        }
    }

    /**
     * 验证value不为空字符串
     *
     * @param value 待验证字符串
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyNotBlank(String value, ResponseStatus errorEnum, Object... errorDescArg)
        throws CorpBusinessException {
        if (StringUtils.isBlank(value)) {
            throw new CorpBusinessException(errorEnum, errorDescArg);
        }
    }

    /**
     * 验证value不为null
     *
     * @param value 待验证对象
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyNotNull(Object value, ResponseStatus errorEnum) throws CorpBusinessException {
        if (value == null) {
            throw new CorpBusinessException(errorEnum);
        }
    }

    /**
     * 验证value不为null
     *
     * @param value 待验证对象
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyNotNull(Object value, ResponseStatus errorEnum, Object... errorDescArg)
        throws CorpBusinessException {
        if (value == null) {
            throw new CorpBusinessException(errorEnum, errorDescArg);
        }
    }

    /**
     * 验证时间格式是否正确
     *
     * @param value 待验证时间字符串
     * @param format 期望的字符串格式
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyLocaleDateTime(String value, String format, ResponseStatus errorEnum)
        throws CorpBusinessException {
        verifyNotBlank(value, errorEnum);
        try {
            LocalDateTime.parse(value, DateTimeFormatter.ofPattern(format));
        } catch (Exception ignored) {
            throw new CorpBusinessException(errorEnum);
        }
    }

    /**
     * 验证时间格式是否正确
     *
     * @param value 待验证时间字符串
     * @param format 期望的字符串格式
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyLocaleDateTime(String value, String format, ResponseStatus errorEnum,
        Object... errorDescArg)
        throws CorpBusinessException {
        verifyNotBlank(value, errorEnum, errorDescArg);
        try {
            LocalDateTime.parse(value, DateTimeFormatter.ofPattern(format));
        } catch (Exception ignored) {
            throw new CorpBusinessException(errorEnum, errorDescArg);
        }
    }

    /**
     * 验证时间格式是否正确
     *
     * @param value 待验证时间字符串
     * @param format 期望的字符串格式
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyZonedDateTime(String value, String format, ResponseStatus errorEnum)
        throws CorpBusinessException {
        verifyNotBlank(value, errorEnum);
        try {
            ZonedDateTime.parse(value, DateTimeFormatter.ofPattern(format));
        } catch (Exception ignored) {
            throw new CorpBusinessException(errorEnum);
        }
    }

    /**
     * 验证时间格式是否正确
     *
     * @param value 待验证时间字符串
     * @param format 期望的字符串格式
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyZonedDateTime(String value, String format, ResponseStatus errorEnum,
        Object... errorDescArg) throws CorpBusinessException {
        verifyNotBlank(value, errorEnum, errorDescArg);
        try {
            ZonedDateTime.parse(value, DateTimeFormatter.ofPattern(format));
        } catch (Exception ignored) {
            throw new CorpBusinessException(errorEnum, errorDescArg);
        }
    }

    /**
     * 自定义验证,function必须返回true，否则抛出异常errorEnum
     *
     * @param function 一串验证代码，验证返回true
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyMust(VerifyFunction function, ResponseStatus errorEnum)
        throws CorpBusinessException {
        if (!function.test()) {
            throw new CorpBusinessException(errorEnum);
        }
    }

    /**
     * 自定义验证,function必须返回true，否则抛出异常errorEnum
     *
     * @param function 一串验证代码，验证返回true
     * @param errorEnum 验证失败抛出的错误码
     * @throws CorpBusinessException 校验失败异常
     */
    public static void verifyMust(VerifyFunction function, ResponseStatus errorEnum, Object... errorDescArg)
        throws CorpBusinessException {
        if (!function.test()) {
            throw new CorpBusinessException(errorEnum, errorDescArg);
        }
    }

    @FunctionalInterface
    public interface VerifyFunction {
        /**
         * 进行校验，true表示校验失败
         * 
         * @return true表示校验失败
         */
        boolean test();
    }
}
